package lgq.xuan.httprequest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.loader.content.Loader;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import lgq.xuan.httprequest.param.BaseMsg;
import lgq.xuan.httprequest.util.sqlite.PhoneCURD;
import lgq.xuan.httprequest.util.sqlite.PhoneHelper;

public class PhoneListActivity extends AppCompatActivity {

    private static final String url = String.format("%s%s", BaseMsg.URI, BaseMsg.PHONE);

    SQLiteOpenHelper phoneHelper;
    private Cursor cursor;

    Intent intent;

    public static String DETAILS_PHONE = "phone-list";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_phone_list);

        intent = getIntent();

        phoneHelper = new PhoneHelper(this);

        ListView phoneList = findViewById(R.id.lits_phone);
        System.out.println(BaseMsg.UID);
        cursor = PhoneCURD.queryOncePhone(this, BaseMsg.UID);
        System.out.println(cursor.getCount());
//        cursor = PhoneCURD.queryAllPhone(this);
        SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_list_item_multiple_choice,  // 安卓内置布局 每行显示一个文本框
                this.cursor,
                new String[]{"name"},
                new int[]{android.R.id.text1},
                0);

        phoneList.setAdapter(simpleCursorAdapter);
        phoneList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        this.registerForContextMenu(phoneList);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.list_menu, menu);
        return true;
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        int itemId = item.getItemId();

        ListView phoneList = findViewById(R.id.lits_phone);
        ListAdapter adapter = phoneList.getAdapter();
        switch (itemId) {
            case R.id.locationAdd:
                Intent intent = new Intent(this, LocationAddActivity.class);
                startActivity(intent);
                break;
            case R.id.locationUpload: // 同步数据，上传
                Log.i(TAG, "onOptionsItemSelected: upload");
                try {
                    uploadMsg();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.locationUploadAll:
                Log.i(TAG, "onOptionsItemSelected: upload");
                try {
                    uploadAll();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.locationSyne: // 同步数据，下载
                download();
                Log.i(TAG, "onOptionsItemSelected: sync");
                break;
            case R.id.locationDelete: // 批量标记删除
                for (long checkedItemId : phoneList.getCheckedItemIds()) {
                    PhoneCURD.signDelete(this, (int) checkedItemId);
                }
                Log.i(TAG, "onOptionsItemSelected: delete");
                break;
            case R.id.allChecked: // 全选
                for (int i = 0; i < adapter.getCount(); i++) {
                    phoneList.setItemChecked(i, true);
                }
                break;
            case R.id.allNoChecked: // 取消全选
                for (int i = 0; i < adapter.getCount(); i++) {
                    phoneList.setItemChecked(i, false);
                }
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    private void uploadAll() throws JSONException {
        if (!BaseMsg.ONLINE) {
            Toast.makeText(this, "当前设备不在线，请重新登录", Toast.LENGTH_SHORT).show();
            return;
        }
        Cursor cursor = PhoneCURD.queryOnePhone(this, BaseMsg.UID);
        cursor.moveToFirst();

        JSONArray phones = new JSONArray();
        do {
            JSONObject phone = getMsg(cursor);
            phones.put(phone);
        } while (cursor.moveToNext());

        uploadToServer(phones);
        PhoneCURD.deleteSigns(this, BaseMsg.UID);
    }

    private void uploadMsg() throws JSONException {
        if (!BaseMsg.ONLINE) {
            Toast.makeText(this, "当前设备不在线，请重新登录", Toast.LENGTH_SHORT).show();
            return;
        }

        ListView phoneList = findViewById(R.id.lits_phone);
        JSONArray phones = new JSONArray();

        for (long checkedItemId : phoneList.getCheckedItemIds()) {
            Cursor cursor = PhoneCURD.queryOnePhoneAllMsg(this, (int) checkedItemId);
            cursor.moveToFirst();
            JSONObject phone = getMsg(cursor);
            phones.put(phone);
        }

        uploadToServer(phones);
        PhoneCURD.deleteSigns(this, BaseMsg.UID);
    }


    private JSONObject getMsg(Cursor cursor) throws JSONException {
        JSONObject phone = new JSONObject();
        int cloudId = cursor.getInt(2);
        phone.put("pid", cloudId);
        String name = cursor.getString(3);
        phone.put("name", name);
        String called = cursor.getString(4);
        phone.put("called", called);
        String phoneNumber = cursor.getString(5);
        phone.put("phone", phoneNumber);
        int isDelete = cursor.getInt(6);
        phone.put("isdelete", isDelete);

        phone.put("uid", BaseMsg.UID);
        return phone;
    }


    private void uploadToServer(JSONArray phones) {

        System.out.println(phones);

        queue = Volley.newRequestQueue(this);
        jsonArrayRequest = new JsonArrayRequest(Request.Method.PUT, url + "/upload", phones,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        try {
                            localSyncAfterUpload(response);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        Toast.makeText(PhoneListActivity.this, "上传成功", Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        System.out.println(error.toString());
                        Toast.makeText(PhoneListActivity.this, "上传失败", Toast.LENGTH_SHORT).show();
                    }
                });
        jsonArrayRequest.setTag(TAG);
        queue.add(jsonArrayRequest);
    }

    private void localSyncAfterUpload(JSONArray phones) throws JSONException {
        for (int i = 0; i < phones.length(); i++) {
            JSONObject phoneJSONObject = phones.getJSONObject(i);

            int pid = phoneJSONObject.getInt("pid");
            String name = phoneJSONObject.getString("name");
            String called = phoneJSONObject.getString("called");
            String phone = phoneJSONObject.getString("phone");

            PhoneCURD.update(this, BaseMsg.UID, pid, name, called, phone);

        }
    }

    private void download() {
        if (!BaseMsg.ONLINE) {
            Toast.makeText(this, "当前设备不在线，请重新登录", Toast.LENGTH_SHORT).show();
            return;
        }

        queue = Volley.newRequestQueue(this);
        jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url + "/p/" + BaseMsg.UID, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        try {
                            syncToLocal(response);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(PhoneListActivity.this, "拉取失败", Toast.LENGTH_SHORT).show();
                    }
                });
        jsonArrayRequest.setTag(TAG);
        queue.add(jsonArrayRequest);
    }

    private void syncToLocal(JSONArray phones) throws JSONException {
        for (int i = 0; i < phones.length(); i++) {
            JSONObject phoneJSONObject = phones.getJSONObject(i);

            ContentValues phone = new ContentValues();
            phone.put("uid", BaseMsg.UID);
            phone.put("cloud_id", phoneJSONObject.getInt("pid"));
            phone.put("name", phoneJSONObject.getString("name"));
            phone.put("called", phoneJSONObject.getString("called"));
            phone.put("phone", phoneJSONObject.getString("phone"));
            phone.put("isdelete", phoneJSONObject.getInt("isdelete"));

            // 插入本地数据库，数据库结构需改建
            PhoneCURD.insert(this, phone);
        }
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        getMenuInflater().inflate(R.menu.list_context_menu, menu);
    }

    public static String IS_UPDATE = "is_update";

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        AdapterView.AdapterContextMenuInfo menuInfo =
                (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        long id = menuInfo.id;
        Intent intent;

        switch (item.getItemId()) {
            case R.id.look: // 本地查看
                Log.i(TAG, "onContextItemSelected: look");
                intent = new Intent(this, DetailsActivity.class);
                intent.putExtra(DETAILS_PHONE, (int) id);
                intent.putExtra(IS_UPDATE, false);
                startActivity(intent);
                break;
            case R.id.update: // 本地修改，不影响远程
                Log.i(TAG, "onContextItemSelected: update");
                intent = new Intent(this, DetailsActivity.class);
                intent.putExtra(DETAILS_PHONE, (int) id);
                intent.putExtra(IS_UPDATE, true);
                startActivity(intent);
                break;
            case R.id.delete: // 本地标记删除，上传后真正删除

                PhoneCURD.signDelete(this, (int) id);
                Log.i(TAG, "onContextItemSelected: delete  " + item.getOrder() + "\t" + id);
                break;
        }

        return super.onContextItemSelected(item);
    }

    JsonArrayRequest jsonArrayRequest;

    RequestQueue queue;

    public static final String TAG = "list-info";


    @Override
    protected void onStop() {
        super.onStop();
        if (queue != null) {
            queue.cancelAll(TAG);
        }
    }

    public void refresh(View r) {

        int uid = intent.getIntExtra(MainActivity.LOGIN_UID, 0);

        @SuppressLint("DefaultLocale") String ul = String.format("%s/%d", url, uid);
        queue = Volley.newRequestQueue(this);

        jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, ul, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        phoneHelper = new PhoneHelper(PhoneListActivity.this);
                        for (int i = 0; i < response.length(); i++) {
                            try (SQLiteDatabase db = phoneHelper.getWritableDatabase()) {

                                JSONObject jsonObject = response.getJSONObject(i);
                                int pid = jsonObject.getInt("pid");
                                String name = jsonObject.getString("name");
                                String called = jsonObject.getString("called");
                                String phone = jsonObject.getString("phone");

//                                long insert = PhoneCURD.insert(db, pid, name, called, phone);
//                                if (insert < 0) {
//                                    PhoneCURD.update(db, pid, name, called, phone);
//                                }
                            } catch (JSONException | SQLException e) {
                                Log.e(TAG, "onResponse: " + e.getMessage());
                            }
                        }

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e(TAG, "onErrorResponse: " + error.toString());
                    }
                });

        jsonArrayRequest.setTag(TAG);
        queue.add(jsonArrayRequest);

//        ListView listPhone = findViewById(R.id.lits_phone);

//        Cursor newCursor = db.query("phone", new String[]{"_id", "name", "called"}, null, null, null, null, null);
//
//        CursorAdapter adapter = (CursorAdapter) listPhone.getAdapter();
//
//        adapter.changeCursor(newCursor);
//
//        cursor = newCursor;

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cursor.close();
        try {
            if (PhoneCURD.db != null) {
                PhoneCURD.db.close();
            }
        } catch (Exception e) {
            e.getMessage();
        }

    }
}
